package com.pay.ioopos.support.scan;

/**
 * IC卡接收指令类型列表
 * @author Moyq5
 * @date 2020年1月15日
 */
public enum IcReceiveCmd {
    FIND(0x03, true, "卡号读取成功"),
    FIND_ERR(0xE2, false, "卡号读取失败"),
    READ(0x04, true, "块数据读取成功"),
    READ_ERR(0xE3, false, "块数据读取失败"),
    WRITE(0x05, true, "块数据写入成功"),
    WRITE_ERR(0xE4, false, "块数据写入失败"),
    INIT_WALLET(0x06, true, "钱包初始化成功"),
    INIT_WALLET_ERR(0xE5, false, "钱包初始化失败"),
    READ_WALLET(0x07, true, "钱包读取成功"),
    READ_WALLET_ERR(0xE6, false, "钱包读取失败"),
    CHARGE_WALLET(0x08, true, "钱包充值成功"),
    CHARGE_WALLET_ERR(0xE7, false, "钱包充值失败"),
    EXPENSE_WALLET(0x09, true, "钱包扣款成功"),
    EXPENSE_WALLET_ERR(0xE8, false, "钱包扣款失败"),
    BACKUP_WALLET(0x0A, true, "钱包备份成功"),
    BACKUP_WALLET_ERR(0xE9, false, "钱包备份失败"),
    SLEEP_WALLET(0x0B, true, "钱包休眠成功"),
    SLEEP_WALLET_ERR(0xEA, false, "钱包休眠失败");

    private byte value;
    private boolean isSuccess;
    private String descr;

    private byte[] data;

    IcReceiveCmd(int value, boolean isSuccess, String descr) {
        this.value = (byte)value;
        this.isSuccess = isSuccess;
        this.descr = descr;
    }

    public static IcReceiveCmd parse(byte[] data) throws Exception {
        if (data[0] != (byte)0xFE) {
            throw new Exception("信息头有误");
        }
        if (data[1] != data.length - 2) {
            throw new Exception("长度有误");
        }
        int index = data.length - 1;
        byte check = 0;
        for (int i = 1; i < index; i++) {
            check ^= data[i];
        }
        if (check != data[index]) {
            throw new Exception("校验值有误");
        }
        byte cmd = data[2];
        IcReceiveCmd[] cmds = values();
        for (int i = 0; i < cmds.length; i++) {
            if (cmds[i].value() == cmd) {
                cmds[i].setData(data);
                return cmds[i];
            }
        }
        throw new Exception("非法指令[" + Integer.toHexString(cmd) + "]");
    }

    public boolean isSuccess() {
        return isSuccess;
    }

    public String getDescr() {
        return descr;
    }

    public byte[] getData() {
        int len = data[1] - 2;
        if (len <= 0) {
            return null;
        }
        byte[] bytes = new byte[len];
        for (int i = 0; i < len; i++) {
            bytes[i] = data[i + 3];
        }
        return bytes;
    }

    private byte value() {
        return value;
    }

    private void setData(byte[] data) {
        this.data = data;
    }

}
